// CZ 类型信息系统 - 完全独立实现
// 不依赖 std 的 @typeInfo

// ============ 类型分类 ============

pub const TypeKind = enum {
    int,
    float,
    bool,
    pointer,
    slice,
    array,
    struct_type,
    enum_type,
    union_type,
    optional,
    error_union,
    function,
    void_type,
    unknown,
};

// ============ 类型信息 ============

pub const TypeInfo = struct {
    kind: TypeKind,
    size: usize,
    alignment: usize,
    
    // 指针/切片信息
    child_type: ?*const TypeInfo = null,
    is_const: bool = false,
    
    // 数组信息
    array_len: ?usize = null,
};

// ============ 类型检测函数 ============

pub fn getTypeInfo(comptime T: type) TypeInfo {
    const size = @sizeOf(T);
    const alignment = @alignOf(T);
    
    // 检测基本类型
    if (T == void) {
        return TypeInfo{
            .kind = .void_type,
            .size = 0,
            .alignment = 1,
        };
    }
    
    if (T == bool) {
        return TypeInfo{
            .kind = .bool,
            .size = size,
            .alignment = alignment,
        };
    }
    
    // 检测整数类型
    if (isIntType(T)) {
        return TypeInfo{
            .kind = .int,
            .size = size,
            .alignment = alignment,
        };
    }
    
    // 检测浮点类型
    if (isFloatType(T)) {
        return TypeInfo{
            .kind = .float,
            .size = size,
            .alignment = alignment,
        };
    }
    
    // 检测切片类型
    if (isSliceType(T)) {
        return TypeInfo{
            .kind = .slice,
            .size = size,
            .alignment = alignment,
        };
    }
    
    // 默认返回未知类型
    return TypeInfo{
        .kind = .unknown,
        .size = size,
        .alignment = alignment,
    };
}

// ============ 类型判断辅助函数 ============

pub fn isIntType(comptime T: type) bool {
    return T == i8 or T == i16 or T == i32 or T == i64 or T == i128 or T == isize or
           T == u8 or T == u16 or T == u32 or T == u64 or T == u128 or T == usize or
           T == c_short or T == c_ushort or T == c_int or T == c_uint or
           T == c_long or T == c_ulong or T == c_longlong or T == c_ulonglong;
}

pub fn isFloatType(comptime T: type) bool {
    return T == f16 or T == f32 or T == f64 or T == f80 or T == f128 or
           T == c_longdouble;
}

pub fn isSliceType(comptime T: type) bool {
    // 简单检测：如果类型大小等于两个指针大小，可能是切片
    return @sizeOf(T) == @sizeOf(usize) * 2;
}

pub fn isPointerType(comptime T: type) bool {
    return @sizeOf(T) == @sizeOf(usize);
}

// ============ 切片类型辅助 ============

pub fn SliceChild(comptime T: type) type {
    // 这是一个编译时函数，用于获取切片的子类型
    // 例如：SliceChild([]u8) 返回 u8
    // 使用类型推断而不是 undefined
    const DummyArray = [1]T{};
    const dummy_slice: T = DummyArray[0..1];
    return @TypeOf(dummy_slice[0]);
}

pub fn isSlice(comptime T: type) bool {
    // 检测是否是切片类型
    // 切片的特征：有 ptr 和 len 字段
    if (@sizeOf(T) != @sizeOf(usize) * 2) return false;
    
    // 尝试访问切片的特性
    const dummy: T = undefined;
    _ = dummy.ptr;
    _ = dummy.len;
    return true;
}

// ============ 类型转换辅助 ============

pub fn ptrCast(comptime T: type, ptr: anytype) T {
    return @ptrCast(ptr);
}

pub fn alignCast(comptime alignment: comptime_int, ptr: anytype) @TypeOf(ptr) {
    _ = alignment;
    return @alignCast(ptr);
}

pub fn bitCast(comptime T: type, value: anytype) T {
    return @bitCast(value);
}

// ============ 内存操作 ============

pub fn memcpy(dest: []u8, src: []const u8) void {
    for (src, 0..) |byte, i| {
        if (i >= dest.len) break;
        dest[i] = byte;
    }
}

pub fn memset(dest: []u8, value: u8) void {
    for (dest) |*byte| {
        byte.* = value;
    }
}

pub fn memcmp(a: []const u8, b: []const u8) i32 {
    const min_len = if (a.len < b.len) a.len else b.len;
    for (a[0..min_len], b[0..min_len]) |ca, cb| {
        if (ca < cb) return -1;
        if (ca > cb) return 1;
    }
    if (a.len < b.len) return -1;
    if (a.len > b.len) return 1;
    return 0;
}

// ============ 测试 ============

test "type info" {
    const info_u8 = getTypeInfo(u8);
    if (info_u8.kind != .int) return error.TestFailed;
    if (info_u8.size != 1) return error.TestFailed;
    
    const info_f64 = getTypeInfo(f64);
    if (info_f64.kind != .float) return error.TestFailed;
    if (info_f64.size != 8) return error.TestFailed;
    
    const info_bool = getTypeInfo(bool);
    if (info_bool.kind != .bool) return error.TestFailed;
}
